package network.tpb;

import itdb1.commun.HeartBeats;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.InterfaceAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;

import user.LocalUser;
import utils.Configuration;

import network.config.NetworkConfiguration;
import network.config.NetworkConfiguration.PortType;

public class HeartBeater extends Thread {
	
	private DatagramSocket socket ;
	private boolean running ;
	private ArrayList <DatagramPacket> heartBeatPackets ;

	private static final int HEART_BEAT_TIME_DELAY = 10 ;
	
	/**
	 * Start a new HeartBeater that will send a HeartBeat signals.
	 * 
	 * @param port
	 * @throws SocketException if an error occurs creating the UDP socket
	 */
	public HeartBeater (NetworkConfiguration netconf) throws SocketException {
		this.socket = new DatagramSocket () ;
		byte[] heartBeat = (new UserSignalB(new HeartBeats(LocalUser.getLocalUser().getUsername()), null)).serialize() ;
		this.heartBeatPackets = new ArrayList <DatagramPacket> () ;
		for (InterfaceAddress interf : netconf.getAllowedInterfaces()) {
			this.heartBeatPackets.add(new DatagramPacket(heartBeat, heartBeat.length, new InetSocketAddress(interf.getBroadcast(), 
					netconf.getPort(PortType.UDP_SEND)))) ;
		}
	}
	
	/**
	 * Stop the listener thread properly.
	 */
	public void finish () {
		this.running = false ;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Thread#run()
	 */
	public void run () {
		this.running = true ;
		while (this.running) {
			for (DatagramPacket packet : this.heartBeatPackets)  {
				try {
					Configuration.net_debug.println("Sending heartbeat to : " + packet.getSocketAddress()) ;
					this.socket.send(packet) ;
				} 
				catch (SocketTimeoutException e) {
					
				}
				catch (SocketException e) {
					e.printStackTrace();
				} 
				catch (IOException e) {
					e.printStackTrace();
				} 
			}
			synchronized (this) {
				try {
					wait(HEART_BEAT_TIME_DELAY * 1000) ;
				} 
				catch (InterruptedException e) {

				}
			}
		}
		this.socket.close() ;
	}
}
